package com.photoeditor.demo.db;

import android.database.sqlite.SQLiteConstraintException;
import android.opengl.GLES20;
import android.text.TextUtils;
import android.util.Log;

import com.common.base.ComponentContext;
import com.common.base.log.DLog;
import com.common.base.log.RLog;
import com.common.base.utils.AppUtils;
import com.photoeditor.demo.app.TestUser;
import com.photoeditor.demo.model.filter.ImageFilterTools;
import com.photoeditor.demo.model.image.emoji.StickerConstant;
import com.photoeditor.demo.model.preference.SPDataManager;
import com.photoeditor.demo.model.share.ShareImageTools;
import com.photoeditor.demo.model.store.download.DownloadUtils;
import com.photoeditor.demo.model.store.module.LocalPluginUtil;
import com.photoeditor.demo.model.store.module.StoreOnlineBean;
import com.photoeditor.demo.model.store.module.StoreOnlineManager;
import com.photoeditor.demo.model.subscribe.manager.AppVipManager;
import com.photoeditor.demo.util.ExtSdcardUtils;
import com.photoeditor.demo.util.FileUtil;
import com.photoeditor.demo.util.PhoneInfo;
import com.photoeditor.demo.util.PluginVersionUtil;

import org.greenrobot.greendao.query.Query;

import java.io.File;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import static com.photoeditor.demo.db.FilterConstant.STATUS_UNUSE;
import static com.photoeditor.demo.db.FilterConstant.STATUS_USE;
import static com.photoeditor.demo.db.FilterConstant.TYPE_DOWNLOAD;
import static com.photoeditor.demo.model.store.module.StoreOnlineManager.MODULE_ID_FILTER;

/**
 * Created by winn on 17/4/13.
 */

public class DataManager {

    public static final String TAG = DataManager.class.getSimpleName();

    public static final String NORMAL_RES_DIR = com.common.base.utils.FileUtil.getExternalCacheDir(ComponentContext.getContext(),
            ".normal_res", true) + File.separator;

    /**
     * 数据是否已初始化
     */
    public boolean mIsDataInit = false;

    private static DataManager mInstance = null;

    private List<Integer> mCameraIds;
    private List<FilterCategoryBean> mImageFilterCategoryList;

    /** 保存已下载资源 **/
    private List<String> mInstalledRes = new CopyOnWriteArrayList<>();

    public static DataManager getInstance() {
        if (mInstance == null) {
            synchronized (DataManager.class) {
                if (mInstance == null) {
                    mInstance = new DataManager();
                }
            }
        }
        return mInstance;
    }

    private DataManager() {
        mCameraIds = new ArrayList<>();
    }

    public void initData() {
        initFilterDB();
        initStickerDB();
        SPDataManager.setInitDBDataSuccess(true);
//        initPipDB();
        loadAllImageFilterMap();
        // do something in here

        setDataInitSuccess(true);
    }

    public void loadInstalledResData() {
        List<FilterCategoryBean> filterCategory = getAllImageFilterCategory();
        if (filterCategory != null) {
            for (FilterCategoryBean bean : filterCategory) {
                List<FilterBean> filterBeanList = loadFilterByCategoryId(bean.getCategoryId());
                if (filterBeanList != null) {
                    for (FilterBean filter : filterBeanList) {
                        if (!TextUtils.isEmpty(filter.getApkUri())) {
                            addInstalledRes(filter.getPackageName());
                        }
                    }
                }
            }
        }

        ArrayList<ExtraBean> stickerBean = getAllUsableSticker();
        if (stickerBean != null) {
            for (ExtraBean sticker : stickerBean) {
                addInstalledRes(sticker.getPkgName());
            }
        }
    }

    public void release() {
    }

    public boolean isDataInit() {
        return mIsDataInit;
    }

    public void setDataInitSuccess(boolean success) {
        mIsDataInit = success;
    }

    private void loadAllImageFilterMap() {
        if (mImageFilterCategoryList == null) {
            getAllImageFilterCategory();
        }
//        if (mImageFilterCategoryList != null) {
//            for (FilterCategoryBean categoryBean : mImageFilterCategoryList) {
//                loadFilterByCategoryId(categoryBean.getCategoryId());
//            }
//        }
    }

    /**
     * 加载分类id下所有可用的滤镜
     *
     * @param categoryId
     * @return
     */
    public List<FilterBean> loadFilterByCategoryId(String categoryId) {
        ArrayList<FilterBean> ret;
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.CategoryId.eq(categoryId),
                FilterBeanDao.Properties.Status.eq(STATUS_USE)).build();
        ret = (ArrayList<FilterBean>) query.list();
        return ret;
    }

    public boolean isExistFilterCategory(String categoryId) {
        boolean ret = false;
        FilterCategoryBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterCategoryBeanDao();
        Query query = dao.queryBuilder().where(FilterCategoryBeanDao.Properties.CategoryId.eq(categoryId)).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            ret = true;
        }
        return ret;
//        return DataManager.getInstance().isExistFilterForFilterCategory(categoryId);
    }

    public void insertFilterCategory(FilterCategoryBean categoryBean) {
        FilterCategoryBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterCategoryBeanDao();
        if (!isExistFilterCategory(categoryBean.getCategoryId())) {
            categoryBean.setLocalIndex(0);
            dao.insert(categoryBean);
            mImageFilterCategoryList.add(0, categoryBean);
        }
    }
    /**
     * 指定localIndex插入滤镜分类
     *
     * @param categoryBean
     * @param localIndex
     */
    public void insertFilterCategory(FilterCategoryBean categoryBean, int localIndex) {
        FilterCategoryBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterCategoryBeanDao();
        if (!isExistFilterCategory(categoryBean.getCategoryId())) {
            int count = (int) dao.count();
            if (localIndex < count) {
                // 更新数据库中其他的分类locaIndex，不直接使用mImageFilterCategoryList更新，防止其他地方改动mImageFilterCategoryList
                List<FilterCategoryBean> dbData = dao.loadAll();
                for (FilterCategoryBean bean : dbData) {
                    if (bean.getLocalIndex() >= localIndex) {
                        bean.setLocalIndex(bean.getLocalIndex() + 1);
                    }
                }
                dao.updateInTx(dbData);
                // 更新内存中其他的分类locaIndex
                for (FilterCategoryBean bean : mImageFilterCategoryList) {
                    if (bean.getLocalIndex() >= localIndex) {
                        bean.setLocalIndex(bean.getLocalIndex() + 1);
                    }
                }
            } else {
                localIndex = 0;
            }
            categoryBean.setLocalIndex(localIndex);
            mImageFilterCategoryList.add(localIndex, categoryBean);
            dao.insert(categoryBean);
        }
    }

    public void updateFilterCategory(ArrayList<FilterCategoryBean> categoryList) {
        try {
            FilterCategoryBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterCategoryBeanDao();
            mImageFilterCategoryList.clear();
            mImageFilterCategoryList.addAll(categoryList);
            dao.updateInTx(categoryList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void deleteFilterCategoryById(String categoryId) {
        FilterCategoryBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterCategoryBeanDao();
        Query query = dao.queryBuilder().where(FilterCategoryBeanDao.Properties.CategoryId.eq(categoryId)).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            dao.deleteInTx(list);
        }
        for (FilterCategoryBean bean : mImageFilterCategoryList) {
            if (TextUtils.equals(bean.getCategoryId(), categoryId)) {
                mImageFilterCategoryList.remove(bean);
                break;
            }
        }
        // 同时删除分类下滤镜
        deleteFilterByCategoryId(categoryId);
    }

    public String getCategoryIdOfCategoryByPkgName(String pkgName) {
        FilterCategoryBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterCategoryBeanDao();
        Query query = dao.queryBuilder().where(FilterCategoryBeanDao.Properties.PkgName.eq(pkgName)).build();
        List list = query.list();
        String categoryId = "";
        if (list != null && !list.isEmpty()) {
            categoryId = ((FilterCategoryBean) list.get(0)).getCategoryId();
        }
        return categoryId;
    }

    public FilterCategoryBean getFilterCategoryByCategoryId(String categoryId) {
        for (FilterCategoryBean bean : mImageFilterCategoryList) {
            if (TextUtils.equals(bean.getCategoryId(), categoryId)) {
                return bean;
            }
        }
        return null;
    }


    public List<FilterBean> getFilterBeansByCategoryId(String categoryId) {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.CategoryId.eq(categoryId)).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            return list;
        }
        return null;
    }

    private void updateFilterCategoryWhenDelFilter(String categoryId) {
        // 分类下没有滤镜，删除该分类
        List<FilterBean> list = loadFilterByCategoryId(categoryId);
        if (list == null || list.size() == 0) {
            for (FilterCategoryBean bean : mImageFilterCategoryList) {
                if (TextUtils.equals(bean.getCategoryId(), categoryId)) {
                    mImageFilterCategoryList.remove(bean);
                    break;
                }
            }
        }
    }

    /**
     * 是否已经存在滤镜
     *
     * @param pkgName 滤镜包名
     * @return
     */
    public boolean isExistFilter(String pkgName, String categoryId) {
        boolean ret = false;
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder()
                .where(FilterBeanDao.Properties.PackageName.eq(pkgName), FilterBeanDao.Properties.CategoryId.eq(categoryId))
                .build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            FilterBean firstOne = (FilterBean) list.get(0);
            if (firstOne != null && !TextUtils.isEmpty(firstOne.getApkUri())) {
                ret = true;
            }
        }
        return ret;
    }

    public FilterBean getExistFilter(String pkgName, String categoryId) {
        boolean ret = false;
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder()
                .where(FilterBeanDao.Properties.PackageName.eq(pkgName), FilterBeanDao.Properties.CategoryId.eq(categoryId))
                .build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            FilterBean firstOne = (FilterBean) list.get(0);
            if (firstOne != null && !TextUtils.isEmpty(firstOne.getApkUri())) {
                return firstOne;
            }
        }
        return null;
    }


    public boolean isExistFilterForFilterCategory(String categoryId) {
        boolean ret = true;
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        List<FilterBean> list = dao.queryBuilder().where(FilterBeanDao.Properties.CategoryId.eq(categoryId)).build().list();
        if (list != null && !list.isEmpty()) {
            for (FilterBean bean: list) {
                if (bean != null && (bean.getApkUri() == null || TextUtils.isEmpty(bean.getApkUri()))) {
                    ret = false;
                }
            }
        }
        DLog.d("existLog", "category id: " + categoryId + "  exsit: " + ret);
        return ret;
    }

    /**
     * @param filters
     */
    public void insertFilters(ArrayList<FilterBean> filters) {
        if (filters == null || filters.size() <= 0) {
            return;
        }
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Iterator<FilterBean> iterator = filters.iterator();
        while (iterator.hasNext()) {
            FilterBean bean = iterator.next();
            if (isExistFilter(bean.getPackageName(), bean.getCategoryId())) {
                iterator.remove();
            }
        }
        int dbCount = (int) dao.count();
        if (filters != null && filters.size() > 0) {
            for (int i = 0; i < filters.size(); ++i) {
                FilterBean bean = filters.get(i);
                addInstalledRes(bean.getPackageName());
                bean.setLocalIndex(dbCount + i);
            }
        }
        //由于FilterBean的id是自动生成的，所以这里没法自动去替换相同的数据，只能手动
        insertOrReplaceInTx(dao, filters);
    }

    private void insertOrReplaceInTx(FilterBeanDao dao, List<FilterBean> list) {
        if (dao == null || list == null || list.isEmpty()) {
            return;
        }
        for (FilterBean bean: list) {
            String pkgName = bean.getPackageName();
            String categoryId = bean.getCategoryId();
            if (!TextUtils.isEmpty(pkgName)) {
                List<FilterBean> datas = dao.queryBuilder()
                        .where(FilterBeanDao.Properties.PackageName.eq(pkgName), FilterBeanDao.Properties.CategoryId.eq(categoryId))
                        .build()
                        .list();
                if (datas != null && !datas.isEmpty()) {
                    FilterBean firstOne = datas.get(0);
                    firstOne.setApkUri(bean.getApkUri());
                    dao.insertOrReplace(firstOne);
                } else {
                    dao.insert(bean);
                }
            }
        }
    }

    /**
     * 插入滤镜,新滤镜位置排最后
     * 注意：调用此方法插入滤镜前需要判断是否已插入新的滤镜分类
     *
     * @param filterBean
     */
    public void insertFilter(FilterBean filterBean) {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        if (!isExistFilter(filterBean.getPackageName(), filterBean.getCategoryId())) {
            addInstalledRes(filterBean.getPackageName());
            // 新插入滤镜位置排最后
            filterBean.setLocalIndex((int) dao.count());
            dao.insert(filterBean);
        }
    }

    /**
     * local界面 ， 删除内置滤镜，其实是更新状态为不可用
     *
     * @param id
     */
    public void deleteInternalFilterById(int id) {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.Id.eq(id)).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            FilterBean bean = (FilterBean) list.get(0);
            bean.setStatus(STATUS_UNUSE);
            dao.update(bean);
            updateFilterCategoryWhenDelFilter(bean.getCategoryId());
        }
    }

    /**
     * 删除分类下的滤镜
     *
     * @param categoryId
     */
    public void deleteFilterByCategoryId(String categoryId) {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.CategoryId.eq(categoryId)).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            for (Object bean : list) {
                delInstalledRes(((FilterBean)bean).getPackageName());
            }
            dao.deleteInTx(list);
        }
    }

    /**
     * 在filter列表点击下载内置滤镜， 把该滤镜状态改为可用
     * 注意：调用此方法插入滤镜前需要判断是否已插入新的滤镜分类
     *
     * @param name
     */
    public void updateInternalFilterByName(String name) {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.Name.eq(name)).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            FilterBean bean = (FilterBean) list.get(0);
            bean.setStatus(FilterConstant.STATUS_USE);
            dao.update(bean);
        }
    }

    /**
     * local界面 ， 删除下载滤镜
     *
     * @param id
     */
    public void deleteLocalFilterById(int id) {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        dao.deleteByKey((long) id);
        // 更新滤镜分类
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.Id.eq(id)).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            FilterBean bean = (FilterBean) list.get(0);
            updateFilterCategoryWhenDelFilter(bean.getCategoryId());
        }
    }

    /**
     * 根据包名删除滤镜
     *
     * @param packageNameList
     */
    public void deleteFilterByPackageNames(ArrayList<String> packageNameList) {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        if (packageNameList == null || packageNameList.size() < 1) {
            //为空， 则删除所有下载的滤镜
            Query query = dao.queryBuilder().where(FilterBeanDao.Properties.Type.eq(TYPE_DOWNLOAD)).build();
            List list = query.list();
            if (list != null && !list.isEmpty()) {
                dao.deleteInTx(list);
                // 更新滤镜分类
                for (Object bean : list) {
                    updateFilterCategoryWhenDelFilter(((FilterBean) bean).getCategoryId());
                }
            }
        } else {
            ArrayList<FilterBean> deleteList = new ArrayList<>();
            for (String pkgName : packageNameList) {
                Query query = dao.queryBuilder().where(FilterBeanDao.Properties.PackageName.eq(pkgName)).build();
                List list = query.list();
                if (list != null && !list.isEmpty()) {
                    deleteList.addAll(list);
                }
            }
            if (deleteList.size() > 0) {
                dao.deleteInTx(deleteList);
                // 更新滤镜分类
                for (FilterBean bean : deleteList) {
                    updateFilterCategoryWhenDelFilter(bean.getCategoryId());
                }
            }
        }
    }

    /**
     * 上下拖动loca，改变顺序后，更新数据库状态。
     *
     * @param listNew
     */
    public void updateNum(List<FilterBean> listNew) {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        dao.updateInTx(listNew);
    }

    /**
     * 根据包名获取滤镜
     *
     * @return
     */
    public FilterBean getLocalFilterByPackageName(String packageName) {
        FilterBean ret = null;
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.PackageName.eq(packageName)).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            FilterBean bean = (FilterBean) list.get(0);
            ret = bean;
        }
        return ret;
    }

    /**
     * 查询所有滤镜 , 过滤掉more , 并且状态可用 , Local界面使用 , num 顺序排列
     *
     * @return
     */
    public ArrayList<FilterBean> getLocalFilterListStatusUse() {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.Status.eq(STATUS_USE)).orderAsc(FilterBeanDao.Properties.LocalIndex).build();
        List<FilterBean> list =  (ArrayList<FilterBean>) query.list();

        ArrayList<FilterBean> result = new ArrayList<>();
        if (!SPDataManager.getArtistAvailable() || !SPDataManager.getArtistEnable()) {
            //策略控制不展示艺术滤镜，或者页面因为某些原因不展示
            int size = list.size();
            for (int i = 0; i < size; i++) {
                FilterBean bean = list.get(i);
                if (!TextUtils.equals("5060", bean.getCategoryId())) {
                    result.add(bean);
                }
            }
            return result;
        }
        return (ArrayList)list;
    }

    /**
     * 查询所有滤镜 , 过滤掉more , 并且状态可用 , Local界面使用 , num 顺序排列
     *
     * @return
     */
    public ArrayList<FilterBean> getLocalFilterListStatusUseWithoutArt() {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.Status.eq(STATUS_USE)).orderAsc(FilterBeanDao.Properties.LocalIndex).build();
        List<FilterBean> list =  (ArrayList<FilterBean>) query.list();

        ArrayList<FilterBean> result = new ArrayList<>();
        if (true) {
            //策略控制不展示艺术滤镜，或者页面因为某些原因不展示
            int size = list.size();
            for (int i = 0; i < size; i++) {
                FilterBean bean = list.get(i);
                if (!TextUtils.equals("5060", bean.getCategoryId())) {
                    result.add(bean);
                }
            }
            return result;
        }
        return (ArrayList)list;
    }

    /**
     * 查询所有滤镜，状态为可用，按分类排序
     *数据库的 已下载的
     * @return
     */
    public ArrayList<FilterBean> getLocalFilterListStatusUseByOrder() {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.Status.eq(STATUS_USE)).orderAsc(FilterBeanDao.Properties.LocalIndex).build();
        List<FilterBean> list =  (ArrayList<FilterBean>) query.list();
        return new ArrayList<>(list);
    }

    /**
     * 本地内置不可用(删除)状态
     *
     * @return
     */
    public ArrayList<FilterBean> getLocalFilterListStatusNo() {
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        Query query = dao.queryBuilder().where(FilterBeanDao.Properties.Status.eq(STATUS_UNUSE),
                FilterBeanDao.Properties.Type.eq(FilterConstant.TYPE_BUILDIN)).orderAsc(FilterBeanDao.Properties.LocalIndex).build();
        return (ArrayList<FilterBean>) query.list();
    }

    private void initFilterDB() {
        // 只在第一次启动时初始化
        // 增加判断：如果是新版本，有可能需要更新数据，需要继续往下判断
        boolean isNewVersion = isNewVersion();
        if (SPDataManager.isInitDBDataSuccess() && !isNewVersion) {
            return;
        }
        //由于更新逻辑里有判断，如果数据存在就不更新，所以会导致新数据无法插入数据库
        //原逻辑保持不变，故每次插入数据前，先清除
        clearFilterDB();
        DataManager.getInstance().getAllImageFilterCategory();
        StoreOnlineBean storeOnlineBean = ImageFilterTools.loadInsideFilterBean();
        if (storeOnlineBean != null) {
            ArrayList<StoreOnlineBean> childModules = storeOnlineBean.getChildModules();
            if (childModules != null) {
                for (StoreOnlineBean category : childModules) {
                    String filePath = ImageFilterTools.copyInsideFileToExternalPath(category.getName());
                    if (!TextUtils.isEmpty(filePath)) {
                        DownloadUtils.getInstance().handleFilterCategoryDownloadFinish(filePath,
                                category);
                    }
                }
            }
        }
        //数据插入完毕，更新版本号
        SPDataManager.setAppInstallVersion(AppUtils.getVersionCode(ComponentContext.getContext()));
    }

    private void clearFilterDB() {
        //和insertOrReplaceInTx()对应，只清除 FilterBeanDao 中的数据
        FilterBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterBeanDao();
        dao.deleteAll();
    }

    public List<FilterCategoryBean> getAllImageFilterCategory() {
        if (mImageFilterCategoryList != null) {
            // 拷贝列表，防止外部改变列表，导致异常
            return (List<FilterCategoryBean>) ((ArrayList) mImageFilterCategoryList).clone();
        }
        List<FilterCategoryBean> ret;
        FilterCategoryBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterCategoryBeanDao();
        ret = dao.queryBuilder().orderAsc(FilterCategoryBeanDao.Properties.LocalIndex).orderDesc(FilterCategoryBeanDao.Properties.Id).list();
        mImageFilterCategoryList = (List<FilterCategoryBean>) ((ArrayList) ret).clone();
        return ret;
    }

    /**
     * 这个方法不要过早调用，以免没有拿到配置拿到，读取不到数据
     */
    public List<FilterCategoryBean> loadOrInitFilterCategory() {
        //先查询数据库
        List<FilterCategoryBean> result = new ArrayList<>();
        FilterCategoryBeanDao dao = DBHelper.getInstance().getDaoSession().getFilterCategoryBeanDao();
        List<FilterCategoryBean> data = dao.loadAll();

        StoreOnlineBean rootBean = StoreOnlineManager.getInstance().getFilterCategoryBeanById(MODULE_ID_FILTER);
        if (rootBean == null) {
            //配置文件为空，很可能是后台删除了这些配置，不要返回这些data了
            return result;
        }
        ArrayList<StoreOnlineBean> categoryBeans = rootBean.getChildModules();
        if (categoryBeans == null || categoryBeans.isEmpty()) {
            //同上
            return result;
        }
        int countInDB = (data==null)?0:data.size();
        int countInConfiguration = categoryBeans.size();
        if (countInConfiguration != countInDB) {
            //db中数据和配置文件对不上，以配置文件为主
            ArrayList<FilterCategoryBean> categorydata = new ArrayList<>();
            for (StoreOnlineBean bean: categoryBeans) {
                categorydata.add(StoreOnlineManager.toFilterCategoryBean(bean));
            }
            dao.insertOrReplaceInTx(categorydata);
            result.addAll(categorydata);
        } else {
            //数据一致，返回data
            if (data != null) {
                result.addAll(data);
            }
        }

        //去除掉艺术滤镜的bean
        ArrayList<FilterCategoryBean> newCategorydata = new ArrayList<>();
        if (TestUser.isTestUser()) {
            RLog.d("ArtControllLog", "remote: " + SPDataManager.getArtistAvailable() + "  local: " + SPDataManager.getArtistEnable());
        }
        DLog.d("ArtControllLog", "remote: " + SPDataManager.getArtistAvailable() + "  local: " + SPDataManager.getArtistEnable());
        if (!SPDataManager.getArtistAvailable() || !SPDataManager.getArtistEnable()) {
            //策略控制不展示艺术滤镜，或者页面因为某些原因不展示
            int size = result.size();
            for (int i = 0; i < size; i++) {
                FilterCategoryBean bean = result.get(i);
                if (!TextUtils.equals("5060", bean.getCategoryId())) {
                    newCategorydata.add(bean);
                }
            }
            result = newCategorydata;
        }

        return result;
    }

    /**
     * 这个方法不要过早调用，以免没有拿到配置拿到，读取不到数据
     */
    public List<FilterCategoryBean> loadAllFilterCategory() {
        //先查询数据库
        List<FilterCategoryBean> result = new ArrayList<>();

        StoreOnlineBean rootBean = StoreOnlineManager.getInstance().getFilterCategoryBeanById(MODULE_ID_FILTER);
        if (rootBean == null) {
            //配置文件为空，很可能是后台删除了这些配置，不要返回这些data了
            List<FilterCategoryBean> allImageFilterCategory = getAllImageFilterCategory();
            if (!SPDataManager.getArtistAvailable() || !SPDataManager.getArtistEnable()) {
                Iterator<FilterCategoryBean> iterator = allImageFilterCategory.iterator();
                while (iterator.hasNext()) {
                    FilterCategoryBean next = iterator.next();
                    if (TextUtils.equals("Artistic", next.getName())) {
                        iterator.remove();
                    }
                }
            }
            FilterCategoryBean originalCategoryBean = new FilterCategoryBean();
            originalCategoryBean.setName("Original");
            originalCategoryBean.setCategoryId("0");
            allImageFilterCategory.add(0, originalCategoryBean);
            return allImageFilterCategory;
        }
        ArrayList<StoreOnlineBean> categoryBeans = rootBean.getChildModules();
        if (categoryBeans == null || categoryBeans.isEmpty()) {
            //同上
            List<FilterCategoryBean> allImageFilterCategory = getAllImageFilterCategory();
            if (!SPDataManager.getArtistAvailable() || !SPDataManager.getArtistEnable()) {
                Iterator<FilterCategoryBean> iterator = allImageFilterCategory.iterator();
                while (iterator.hasNext()) {
                    FilterCategoryBean next = iterator.next();
                    if (TextUtils.equals("Artistic", next.getName())) {
                        iterator.remove();
                    }
                }
            }
            FilterCategoryBean originalCategoryBean = new FilterCategoryBean();
            originalCategoryBean.setName("Original");
            originalCategoryBean.setCategoryId("0");
            allImageFilterCategory.add(0, originalCategoryBean);
            return allImageFilterCategory;
        }

        ArrayList<FilterCategoryBean> categorydata = new ArrayList<>();
        for (StoreOnlineBean bean: categoryBeans) {
            categorydata.add(StoreOnlineManager.toFilterCategoryBean(bean));
        }
        result.addAll(categorydata);

        //去除掉艺术滤镜的bean
        ArrayList<FilterCategoryBean> newCategorydata = new ArrayList<>();
        if (TestUser.isTestUser()) {
            RLog.d("ArtControllLog", "remote: " + SPDataManager.getArtistAvailable() + "  local: " + SPDataManager.getArtistEnable());
        }
        DLog.d("ArtControllLog", "remote: " + SPDataManager.getArtistAvailable() + "  local: " + SPDataManager.getArtistEnable());
        if (!SPDataManager.getArtistAvailable() || !SPDataManager.getArtistEnable()) {
            //策略控制不展示艺术滤镜，或者页面因为某些原因不展示
            int size = result.size();
            for (int i = 0; i < size; i++) {
                FilterCategoryBean bean = result.get(i);
                if (!TextUtils.equals("5060", bean.getCategoryId())) {
                    newCategorydata.add(bean);
                }
            }
            result = newCategorydata;
        }
        FilterCategoryBean originalCategoryBean = new FilterCategoryBean();
        originalCategoryBean.setName("Original");
        originalCategoryBean.setCategoryId("0");
        result.add(0, originalCategoryBean);

        return result;
    }

    public List<FilterBean> loadAllFilter() {
        return loadAllFilter(false);
    }

    /**
     * @param withoutVip 不需要vip资源
     * 这个方法不要过早调用，以免没有拿到配置拿到，读取不到数据
     */
    public List<FilterBean> loadAllFilter(boolean withoutVip) {
        //先查询数据库
        List<FilterBean> filterBeans = new ArrayList<>();

        StoreOnlineBean rootBean = StoreOnlineManager.getInstance().getFilterCategoryBeanById(MODULE_ID_FILTER);
        if (rootBean == null) {
            ArrayList<FilterBean> localFilterListStatusUseByOrder = getLocalFilterListStatusUseByOrder();
            if (!SPDataManager.getArtistAvailable() || !SPDataManager.getArtistEnable()) {
                Iterator<FilterBean> iterator = localFilterListStatusUseByOrder.iterator();
                while (iterator.hasNext()) {
                    FilterBean next = iterator.next();
                    if (next.getType() == FilterConstant.TYPE_ARTISTIC) {
                        iterator.remove();
                    }
                }
            }
            //添加原图缩略图
            FilterBean orginalBean = new FilterBean();
            orginalBean.setType(FilterConstant.TYPE_ORIGINAL);
            localFilterListStatusUseByOrder.add(0, orginalBean);
            return localFilterListStatusUseByOrder;
        }
        ArrayList<StoreOnlineBean> categoryBeans = rootBean.getChildModules();
        if (categoryBeans == null || categoryBeans.isEmpty()) {
            //同上
            ArrayList<FilterBean> localFilterListStatusUseByOrder = getLocalFilterListStatusUseByOrder();
            if (!SPDataManager.getArtistAvailable() || !SPDataManager.getArtistEnable()) {
                Iterator<FilterBean> iterator = localFilterListStatusUseByOrder.iterator();
                while (iterator.hasNext()) {
                    FilterBean next = iterator.next();
                    if (next.getType() == FilterConstant.TYPE_ARTISTIC) {
                        iterator.remove();
                    }
                }
            }
            //添加原图缩略图
            FilterBean orginalBean = new FilterBean();
            orginalBean.setType(FilterConstant.TYPE_ORIGINAL);
            localFilterListStatusUseByOrder.add(0, orginalBean);
            return localFilterListStatusUseByOrder;
        }

        //去除掉艺术滤镜的bean
        ArrayList<StoreOnlineBean> newCategorydata = new ArrayList<>();
        if (TestUser.isTestUser()) {
            RLog.d("ArtControllLog", "remote: " + SPDataManager.getArtistAvailable() + "  local: " + SPDataManager.getArtistEnable());
        }
        DLog.d("ArtControllLog", "remote: " + SPDataManager.getArtistAvailable() + "  local: " + SPDataManager.getArtistEnable());
        if (!SPDataManager.getArtistAvailable() || !SPDataManager.getArtistEnable()) {
            //策略控制不展示艺术滤镜，或者页面因为某些原因不展示
            int size = categoryBeans.size();
            for (int i = 0; i < size; i++) {
                StoreOnlineBean bean = categoryBeans.get(i);
                if (!TextUtils.equals("5060", bean.getId())) {
                    newCategorydata.add(bean);
                }
            }
            categoryBeans = newCategorydata;
        }
//        for (FilterCategoryBean categoryBean : categoryBeanList) {
//            filterBeans.addAll(loadOrInitFilter(categoryBean.getCategoryId()));
//        }
        FilterBean filterBean = null;
        boolean isVip = AppVipManager.isVip();
        for (int i = 0; i < categoryBeans.size(); i++) {
            for (StoreOnlineBean itemBean : categoryBeans.get(i).getChildModules()) {
                if(!isVip && withoutVip && itemBean.isBuy()) {
                    //已购买vip忽略
                    continue;
                }
                filterBean = DataManager.getInstance().getExistFilter(itemBean.getPkgName(), itemBean.getCategoryId());
                if (filterBean == null) {
                    filterBean = StoreOnlineManager.toFilterBean(itemBean, "");
                }
                filterBean.setCategoryPosition(i + 1);
                filterBeans.add(filterBean);
            }
        }

        //添加原图缩略图
        FilterBean orginalBean = new FilterBean();
        orginalBean.setType(FilterConstant.TYPE_ORIGINAL);
        filterBeans.add(0, orginalBean);

        return filterBeans;
    }

    /**
     * 对比当前App的版本号与存储在Sp文件中的版本号
     * 用来判断是否是升级后的App
     * @return
     */
    private boolean isNewVersion() {
        int version = SPDataManager.getAppInstallVersion();
        int currVersion = AppUtils.getVersionCode(ComponentContext.getContext());
        return currVersion > version;
    }


    public void setPreferenceSaveLocation(String location) {
        SPDataManager.setPhotoSaveLocation(location);
    }

    public String getPreferenceSaveLocation() {
        String location = SPDataManager.getPhotoSaveLocation();
        if (PhoneInfo.isSupportWriteExtSdCard() && ExtSdcardUtils.isExtSdcardPath(location)) {//如果是5.0及以上  外置sd卡是可以读写的
            boolean hasPermission = ExtSdcardUtils.hasExtSdcardPermission();
            File f = new File(location);
            if (!hasPermission || !f.exists()) {//没有权限
                location = FileUtil.DICM_ROOT_PATH + File.separator + "Camera";
                setPreferenceSaveLocation(location);
                return location;
            }
        } else {
            File f = new File(location);
            if (!f.exists() || !f.canRead() || !f.canWrite()) {//如果当前路径不存在 或者不能读  或者不能写 则设置为默认路径
                location = FileUtil.DICM_ROOT_PATH + File.separator + "Camera";
                setPreferenceSaveLocation(location);
                return location;
            }
        }
        return location;
    }

    /**
     * 获取最大纹理，0为未初始化
     *
     * @return
     */
    public int getMaxTextureSize() {
        return SPDataManager.getMaxTextureSize();
    }

    /**
     * 初始化最大纹理，需要在GL线程执行
     */
    public void initMaxTextureSize() {
        int size = getMaxTextureSize();
        if (size == 0) {
            try {
                IntBuffer ib = IntBuffer.allocate(1);
                GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, ib);
                ib.position(0);
                size = ib.get();
                DLog.d("PreferenceConfig", "max texture size: " + size);
            } catch (Throwable tr) {
            }
            if (size >= 2048) {
                SPDataManager.setMaxTextureSize(size);
            }
        }
    }

    public void recordShareImageTool(String pkgName, String activityName) {
        if (!TextUtils.isEmpty(pkgName) && !TextUtils.isEmpty(activityName) && !ShareImageTools.isDefaultTools(pkgName, activityName)) {
            String tool1PkgName = getShareImageTool1PkgName();
            String tool1ActivityName = getShareImageTool1ActivityName();
            ;
            if (!TextUtils.isEmpty(tool1PkgName) && !TextUtils.isEmpty(tool1ActivityName)) {
                if (tool1PkgName.equals(pkgName) && tool1ActivityName.equals(activityName)) {
                    //同一个工具不需要记录
                } else {
                    SPDataManager.setShareImageTool2PkgName(tool1PkgName);
                    SPDataManager.setShareImageTool2ActivityName(tool1ActivityName);
                    SPDataManager.setShareImageTool1PkgName(pkgName);
                    SPDataManager.setShareImageTool1ActivityName(activityName);
                }
            } else {
                SPDataManager.setShareImageTool1PkgName(pkgName);
                SPDataManager.setShareImageTool1ActivityName(activityName);
            }
        }
    }

    public String getShareImageTool1PkgName() {
        return SPDataManager.getShareImageTool1PkgName();
    }

    public String getShareImageTool1ActivityName() {
        return SPDataManager.getShareImageTool1ActivityName();
    }

    public String getShareImageTool2PkgName() {
        return SPDataManager.getShareImageTool2PkgName();
    }

    public String getShareImageTool2ActivityName() {
        return SPDataManager.getShareImageTool2ActivityName();
    }

    public void recordShareVideoTool(String pkgName, String activityName) {
        if (!TextUtils.isEmpty(pkgName) && !TextUtils.isEmpty(activityName) && !ShareImageTools.isDefaultTools(pkgName, activityName)) {
            String tool1PkgName = getShareVideoTool1PkgName();
            String tool1ActivityName = getShareVideoTool1ActivityName();
            ;
            if (!TextUtils.isEmpty(tool1PkgName) && !TextUtils.isEmpty(tool1ActivityName)) {
                if (tool1PkgName.equals(pkgName) && tool1ActivityName.equals(activityName)) {
                    //同一个工具不需要记录
                } else {
                    SPDataManager.setShareVideoTool2PkgName(tool1PkgName);
                    SPDataManager.setShareVideoTool2ActivityName(tool1ActivityName);
                    SPDataManager.setShareVideoTool1PkgName(pkgName);
                    SPDataManager.setShareVideoTool1ActivityName(activityName);
                }
            } else {
                SPDataManager.setShareVideoTool1PkgName(pkgName);
                SPDataManager.setShareVideoTool1ActivityName(activityName);
            }
        }
    }

    public String getShareVideoTool1PkgName() {
        return SPDataManager.getShareImageTool1PkgName();
    }

    public String getShareVideoTool1ActivityName() {
        return SPDataManager.getShareImageTool1ActivityName();
    }

    public String getShareVideoTool2PkgName() {
        return SPDataManager.getShareImageTool2PkgName();
    }

    public String getShareVideoTool2ActivityName() {
        return SPDataManager.getShareImageTool2ActivityName();
    }

    public synchronized ArrayList<ExtraBean> getAllSticker() {
        ExtraBeanDao dao = DBHelper.getInstance().getDaoSession().getExtraBeanDao();
        return (ArrayList<ExtraBean>) dao.queryBuilder()
                .orderAsc(ExtraBeanDao.Properties.LocalIndex)
                .orderDesc(ExtraBeanDao.Properties.Id).list();
    }

    public synchronized ArrayList<ExtraBean> getAllUsableSticker() {
        ExtraBeanDao dao = DBHelper.getInstance().getDaoSession().getExtraBeanDao();
        Query query = dao.queryBuilder().where(ExtraBeanDao.Properties.Version.le(PluginVersionUtil.getStickerPluginVersionCode()))
                .orderAsc(ExtraBeanDao.Properties.LocalIndex)
                .orderDesc(ExtraBeanDao.Properties.Id).build();
        return (ArrayList<ExtraBean>) query.list();
    }

    public ExtraBean getStickerByPkgName(String pkgName) {
        ExtraBeanDao dao = DBHelper.getInstance().getDaoSession().getExtraBeanDao();
        Query query = dao.queryBuilder().where(ExtraBeanDao.Properties.PkgName.eq(pkgName)).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            return (ExtraBean) list.get(0);
        }
        return null;
    }

    public synchronized void deleteSticker(String pkgName) {
        //如果不是内置的才需要删除
        if (!pkgName.equals(StickerConstant.APK_EMOJI_PKG_NAME)) {
            delInstalledRes(pkgName);
            ExtraBeanDao dao = DBHelper.getInstance().getDaoSession().getExtraBeanDao();
            Query query = dao.queryBuilder().where(ExtraBeanDao.Properties.PkgName.eq(pkgName)).build();
            List list = query.list();
            if (list != null && !list.isEmpty()) {
                dao.deleteInTx(list);
            }
        }
    }

    public synchronized void deleteSticker(String pkgName, int resType) {
        if (!pkgName.equals(StickerConstant.APK_EMOJI_PKG_NAME)) {
            delInstalledRes(pkgName);
            ExtraBeanDao dao = DBHelper.getInstance().getDaoSession().getExtraBeanDao();
            Query query = dao.queryBuilder().where(ExtraBeanDao.Properties.PkgName.eq(pkgName),
                    ExtraBeanDao.Properties.ResType.eq(resType)).build();
            List list = query.list();
            if (list != null && !list.isEmpty()) {
                dao.deleteInTx(list);
            }
        }
    }

    public synchronized void insertOrUpdateSticker(ExtraBean bean) {
        if (bean == null) {
            return;
        }
        addInstalledRes(bean.getPkgName());
        ExtraBeanDao dao = DBHelper.getInstance().getDaoSession().getExtraBeanDao();
        Query query = dao.queryBuilder().where(ExtraBeanDao.Properties.PkgName.eq(bean.getPkgName())).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            dao.delete((ExtraBean) list.get(0));
        }
        dao.insert(bean);
    }

    public synchronized void replaceStickers(List<ExtraBean> allSticker) {
        ExtraBeanDao dao = DBHelper.getInstance().getDaoSession().getExtraBeanDao();
        dao.deleteAll();
        if (allSticker == null || allSticker.size() == 0) {
            return;
        }
        dao.insertOrReplaceInTx();
        dao.insertInTx(allSticker);
    }

    public boolean isExistSticker(String pkgName) {
        boolean ret = false;
        ExtraBeanDao dao = DBHelper.getInstance().getDaoSession().getExtraBeanDao();
        Query query = dao.queryBuilder().where(ExtraBeanDao.Properties.PkgName.eq(pkgName)).build();
        List list = query.list();
        if (list != null && !list.isEmpty()) {
            ret = true;
        }
        return ret;
    }

    private void initStickerDB() {
        DLog.v("tests", "init sticker");
        // 只在第一次启动时初始化
        if (SPDataManager.isInitDBDataSuccess()) {
            return;
        }
        ExtraBeanDao dao = DBHelper.getInstance().getDaoSession().getExtraBeanDao();
        if (dao.count() > 0) {
            return;
        }
        //内置sticker
        ArrayList<ExtraBean> list = new ArrayList<>();
        int i = 0;
        for (String pkgName : LocalPluginUtil.INSIDE_STICKER_PKGNAME) {
            if (LocalPluginUtil.copyInsideFileToExternalPath(pkgName)) {
                ExtraBean extraBean = ExtraBean.create(pkgName,
                        pkgName,
                        ExtraBean.TYPE_OUTER_NOT_NEED_BUY,
                        i++,
                        false,
                        1,
                        ExtraBean.RES_TYPE_UNINSTALLED,
                        LocalPluginUtil.generateLocalFilePath(LocalPluginUtil.STICKER_PLUGIN_FOLDER_PATH, pkgName),
                        false);
                list.add(extraBean);
            }
        }
        dao.insertInTx(list);
    }

    public boolean isExistNormalResFile(String key) {
        boolean ret = false;
        String path = NORMAL_RES_DIR + key;
        File file = new File(path);
        if (file.exists()) {
            ret = true;
        }
        return ret;
    }

    public String getNormalResFile(String key) {
        String path = NORMAL_RES_DIR + key;
        return path;
    }

    public boolean isInstalled(String pkgName) {
        if (TextUtils.isEmpty(pkgName)) {
            return false;
        }
        return mInstalledRes.contains(pkgName);
    }

    public void addInstalledRes(String pkgName) {
        if (TextUtils.isEmpty(pkgName)) {
            return;
        }
        if (!isInstalled(pkgName)) {
            mInstalledRes.add(pkgName);
        }
    }

    public void delInstalledRes(String pkgName) {
        if (TextUtils.isEmpty(pkgName)) {
            return;
        }
        mInstalledRes.remove(pkgName);
    }



    //about FaceFragment
    public void insertFaceBean(FaceImgBean faceImgBean) {
        FaceImgBeanDao dao = DBHelper.getInstance().getDaoSession().getFaceImgBeanDao();
        try{
            dao.insert(faceImgBean);
        }catch (SQLiteConstraintException exception){
            Log.e(TAG, "exception: "+exception.getMessage());
        }
    }

    public FaceImgBean getFaceUriBean(String path){
        FaceImgBeanDao dao = DBHelper.getInstance().getDaoSession().getFaceImgBeanDao();
        return dao.queryBuilder().where(FaceImgBeanDao.Properties.Path.eq(path)).unique();
    }

    public List<FaceImgBean> getCameraFaceUriBeans(boolean isCheck){
        FaceImgBeanDao dao = DBHelper.getInstance().getDaoSession().getFaceImgBeanDao();
        return dao.queryBuilder().where(FaceImgBeanDao.Properties.IsChecked.eq(true)).list();
    }

    public void updateFaceUriBean(FaceImgBean faceImgBean){
        FaceImgBeanDao dao = DBHelper.getInstance().getDaoSession().getFaceImgBeanDao();
        dao.update(faceImgBean);
    }
}
